package com.yukefms.rule;

import com.yukefms.common.ListTools;
import com.yukefms.rule.formula.SimpleStageBAFormula;
import com.yukefms.rule.formula.interfaces.DynamicBAFormula;
import com.yukefms.rule.formula.interfaces.StageBAFormula;
import com.yukefms.rule.formula.interfaces.StaticBAFormula;
import com.yukefms.rule.interfaces.RuleBuilder;

import java.util.List;

/**
 * @Description the TriggerResponseBARule is specifying following action pattern:
 *
 *
 *
 * @Author Ping
 * @Date 2021/6/16 1:01
 **/
public class TriggerResponseBARule extends AbstractBARule {
    protected StaticBAFormula trigger ;
    protected DynamicBAFormula dynamic ;
    protected StaticBAFormula response ;
    protected StaticBAFormula invariant ;
    protected StageBAFormula currentStage ;

    public TriggerResponseBARule(final String ruleName, final StaticBAFormula trigger,final DynamicBAFormula dynamic,
                                   final StaticBAFormula response, final StaticBAFormula invariant) {
        super(ruleName);
        this.trigger = trigger;
        this.response = response;
        this.invariant = invariant;
        this.dynamic = dynamic ;
        this.currentStage = new SimpleStageBAFormula(this.dynamic, this.response) ;
    }

    public TriggerResponseBARule(final String ruleName, final StaticBAFormula trigger, StageBAFormula stage, final StaticBAFormula invariant) {
        super(ruleName);
        this.trigger = trigger;
        this.response = stage.response() ;
        this.invariant = invariant;
        this.dynamic = stage.dynamic() ;
        this.currentStage = stage ;
    }

    @Override
    public StaticBAFormula getTrigger() {
        return this.trigger;
    }

    @Override
    public StaticBAFormula getResponse() {
        return this.response;
    }

    @Override
    public StaticBAFormula getInvariant() {
        return this.invariant;
    }

    @Override
    public DynamicBAFormula getDynamic() {
        return this.dynamic;
    }

    @Override
    public StageBAFormula currentStage() {
        return this.currentStage;
    }

    @Override
    public List<String> getInvolvedJointTypes() {
        List<String> involvedJointTypes = this.trigger.relatedJointTypes() ;
        ListTools.addAllNoDumplicate(involvedJointTypes, this.response.relatedJointTypes()); ;
        ListTools.addAllNoDumplicate(involvedJointTypes, this.invariant.relatedJointTypes()) ;
        ListTools.addAllNoDumplicate(involvedJointTypes, this.dynamic.relatedJointTypes());

        return involvedJointTypes;
    }
    public static TriggerResponseRuleBuilder builder() {
        return new TriggerResponseRuleBuilder() ;
    }
    public static class TriggerResponseRuleBuilder implements RuleBuilder {
        StaticBAFormula trigger ;
        StaticBAFormula response ;
        StaticBAFormula invariant ;
        DynamicBAFormula dynamic ;
        StageBAFormula stage ;
        String ruleName ;

        public TriggerResponseRuleBuilder setTrigger(StaticBAFormula trigger) {
            this.trigger = trigger ;
            return this ;
        }
        public TriggerResponseRuleBuilder setResponse(StaticBAFormula response) {
            this.response = response ;
            return this ;
        }
        public TriggerResponseRuleBuilder setInvariant(StaticBAFormula invariant) {
            this.invariant = invariant;
            return this ;
        }

        public TriggerResponseRuleBuilder setDynamic(DynamicBAFormula dynamic) {
            this.dynamic = dynamic ;
            return this ;
        }
        public TriggerResponseRuleBuilder setRuleName(String ruleName) {
            this.ruleName = ruleName ;
            return this ;
        }
        public TriggerResponseRuleBuilder setStage(StageBAFormula stage) {
            this.stage = stage ;
            return this;
        }

        public TriggerResponseBARule build() {
            try {
                if (this.trigger == null) {
                    throw new IllegalArgumentException("The trigger formula is null.");
                }
                if (this.invariant == null) {
                    throw new IllegalArgumentException("The invariant formula is null.");
                }
                if (this.ruleName == null) {
                    throw new IllegalArgumentException("The ruleName of formula is null.");
                }
                if (this.stage == null) {
                    if (this.response == null) {
                        throw new IllegalArgumentException("The response formula is null.");
                    }
                    if (this.dynamic == null) {
                        throw new IllegalArgumentException("The response formula is null.");
                    }
                } else {
                    return new TriggerResponseBARule(this.ruleName, this.trigger, this.stage, this.invariant) ;
                }
            } catch (IllegalArgumentException e) {
                return null;
            }

            return new TriggerResponseBARule(this.ruleName, this.trigger, this.dynamic, this.response, this.invariant);
        }

    }



}
